home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagd_f.zip / ENCRYPT.SWG / 0018_Xor Encryption-Decryption.pas < prev    next >
Pascal/Delphi Source File  |  1994-05-25  |  12KB  |  396 lines

  1. (* $Header:   A:/vcs/mash.pav   1.0   15 Jul 1991  7:21:38   K_McCoy  $ *)
  2. (****************************************************************************)
  3.  
  4. UNIT MASH;
  5.  
  6. {$IFDEF DOCUMENTATION}
  7.  
  8. (****************************************************************************)
  9.  *  
  10.  *  $Log:   A:/vcs/mash.pav  $
  11.  * 
  12.  *    Rev 1.0   15 Jul 1991  7:21:38   K_McCoy
  13.  *    Added encryption unit, cleaned up.
  14.  * 
  15.  *  
  16. (****************************************************************************)
  17.  
  18. {$V-}
  19.  
  20.  
  21.                   Mash - The McCoy & Associates File Mangler
  22.  
  23.     Purpose:
  24.  
  25.  
  26.     General purpose text file encrypter.  Keeps the honest people honest.
  27.     Does simple XOR of text characters with user settable key.  Creates
  28.     a binary file with the extension .CRP containing the encrypted text.
  29.     Binary files will be a little shorter than their ascii counterparts
  30.     as there will be no CR/LF delimiters: only a length byte preceeding
  31.     each "line" of binary characters.  There is a 255 character limit on
  32.     the text files, but no limit on the number of lines (up to the capacity
  33.     of the disk).
  34.  
  35.     Drawbacks:  This is nowhere near as secure as DES algorithm, although
  36.     it is much faster.  This unit won't keep the CIA / KGB out of your
  37.     financial records for long, but it might work on your ex-wife
  38.     and her laywer.
  39.  
  40.     Note:  This unit uses the TPSTRING unit from Turbo Power.  You could
  41.     easily change this to use the OPSTRING unit or write your own
  42.     Trim [trailing blanks] function.
  43.  
  44.     I wrote this for an automated test program to keep unauthorized people
  45.     from changing the test specifications out on the assembly line.
  46.     (You wouldn't want airplanes falling on your head, would you?)
  47.  
  48.     Suggested improvements:
  49.  
  50.     Allow other file extensions for input and output files.
  51.     Modify this to work with binary input files.
  52.     Modify the Mangle routine to not reset to the beginning of the key on each
  53.     line of text.
  54.  
  55.     Public Domain, but be nice and give me credit if you use it in your
  56.     own stuff.
  57.  
  58.     _Use at your own risk_  If the KGB de-encrypts your Mangled bowling
  59.     scores, tough!
  60.  
  61.     Do an IO redirect of complaints to NUL.  Questions may be sent to:
  62.  
  63.     Kevin McCoy - CompuServe ID# [72470,1233]
  64.     2217 Aspenpark Ct.
  65.     Thousand Oaks, CA 91362-1731
  66.  
  67.  
  68.                                 Sample Usage:
  69. USES
  70.     DOS,
  71.     CRT,
  72.     MASH;
  73. VAR
  74.     Strg,
  75.     InName         : STRING;
  76.     M              : Mangler;
  77. BEGIN                             {main}
  78.     ClrScr;
  79.  
  80.     WRITE('Enter name of .CFG file: ');
  81.     READLN(InName);
  82.  
  83.     {I think this came from an old "Man from U.N.C.L.E." episode}
  84.     M.SetSequence('OuR CaRs On IcE');
  85.  
  86.     {open the two files}
  87.     IF NOT M.Init(InName, MASHMODE) THEN BEGIN
  88.         WRITELN(M.MashError);
  89.         HALT(1);
  90.     END;
  91.  
  92.     {encrypt the .CFG file}
  93.     IF NOT M.MashFile THEN BEGIN
  94.         WRITELN(M.MashError);
  95.         HALT(1);
  96.     END;
  97.  
  98.     {close the files}
  99.     M.Done;
  100.  
  101.     {Open just the encrypted file}
  102.     IF NOT M.Init(InName, UNMASHMODE) THEN BEGIN
  103.         WRITELN(M.MashError);
  104.         HALT(1);
  105.     END;
  106.  
  107.     {read and decrypt each line until EOF}
  108.     WHILE M.Getline(Strg) DO
  109.         WRITELN(Strg);
  110.  
  111.     {close the .CRP file}
  112.     M.Done;
  113.  
  114. END; {of sample program}
  115.  
  116.  
  117. {$ENDIF}
  118. { The real stuff starts here... }
  119.  
  120. INTERFACE
  121.  
  122. TYPE
  123.     MMType         = (MASHMODE, UNMASHMODE, SOURMASH);
  124.  
  125.     Mangler        = OBJECT
  126.                          TFile          : TEXT;
  127.                          BFile          : FILE;
  128.                          LastError      : WORD;
  129.                          FileName       : STRING;
  130.                          InitMode       : MMType;
  131.                          FUNCTION Init(Fname : STRING; Mode : MMType) :
  132. BOOLEAN;
  133.                          FUNCTION Getline(VAR Line : STRING) : BOOLEAN;
  134.                          FUNCTION MashFile : BOOLEAN;
  135.                          FUNCTION  MashError(VAR S : STRING) : BOOLEAN;
  136.                          PROCEDURE SetSequence(Seq : STRING);
  137.                          PROCEDURE Done;
  138.                      END;
  139.  
  140.    
  141. (****************************************************************************)
  142.  
  143. IMPLEMENTATION
  144.  
  145. USES
  146.     {.U-}
  147.     TPSTRING
  148.     {.U+}
  149.     ;
  150.  
  151. CONST
  152.     {Default key.  May be reset with the SetSequence method}
  153.     Id             : STRING =
  154. '^%12hY7eujEDZ|R9a341~~#2DBC3fn7mSDVvUY@hbFD`6093fdk79*7a-|-  Q`';
  155.  
  156.     {error number constants}
  157.     INVINAM = 500;
  158.     INVINIT = INVINAM + 1;
  159.     CORRUPT = INVINIT + 1;
  160.  
  161.  
  162.    
  163. (****************************************************************************)
  164.  
  165.     FUNCTION Mangle(L : STRING) : STRING;
  166.         { Low budget encryption / decryption of Line}
  167.     VAR
  168.         I              : INTEGER;
  169.     BEGIN
  170.         FOR I := 1 TO LENGTH(L) DO
  171.             L[I] := CHR(ORD(L[I]) XOR NOT(ORD(Id[I MOD LENGTH(Id) + 1])));
  172.         Mangle := L;
  173.     END;
  174.  
  175.    
  176. (****************************************************************************)
  177.  
  178.     FUNCTION Mangler.Init(Fname : STRING; Mode : MMType) : BOOLEAN;
  179.         {- Gozintas:  Fname = Name (no extension) of the input/output files}
  180.         {             Mode  = MASHMODE / UNMASHMODE (encrypt / decrypt)    }
  181.         {  Gozoutas:  TRUE if everything was OK, FALSE if not              }
  182.     VAR
  183.         InName,
  184.         OutName        : STRING;
  185.     BEGIN
  186.         InitMode := Mode;
  187.         FileName := Fname;
  188.         Init := TRUE;
  189.         IF LENGTH(Trim(Fname)) = 0 THEN BEGIN
  190.             LastError := INVINAM;
  191.             Init := FALSE;
  192.             EXIT;
  193.         END;
  194.         InName := Fname + '.CFG';
  195.         OutName := Fname + '.CRP';
  196.  
  197.         { Open the appropriate file(s) }
  198.  
  199.         IF Mode = MASHMODE THEN BEGIN
  200.             ASSIGN(TFile, InName); {open data files}
  201.             {$I-}
  202.             RESET(TFile);
  203.             {$I+}
  204.             LastError := IORESULT;
  205.             IF LastError <> 0 THEN BEGIN
  206.                 {crash if file error}
  207.                 Init := FALSE;
  208.                 EXIT;
  209.             END;
  210.             ASSIGN(BFile, OutName);
  211.             {$I-}
  212.             REWRITE(BFile, 1);
  213.             {$I+}
  214.             LastError := IORESULT;
  215.             IF LastError <> 0 THEN BEGIN
  216.                 {crash if file error}
  217.                 Init := FALSE;
  218.                 EXIT;
  219.             END;
  220.             Init := TRUE;
  221.         END
  222.         ELSE BEGIN
  223.             ASSIGN(BFile, OutName); {open data files}
  224.             {$I-}
  225.             RESET(BFile, 1);
  226.             {$I+}
  227.             LastError := IORESULT;
  228.             IF LastError <> 0 THEN BEGIN
  229.                 {crash if file error}
  230.                 Init := FALSE;
  231.                 EXIT;
  232.             END;
  233.         END;
  234.     END;
  235.  
  236.    
  237. (****************************************************************************)
  238.  
  239.     FUNCTION Mangler.Getline(VAR Line : STRING) : BOOLEAN;
  240.         {- Read a single line of binary gunk from the MSH file and decrypt it}
  241.         {  Gozintas = Nothing                                                }
  242.         {  Gozoutas:  Line = Decrypted ASCII string                          }
  243.         {             Returns TRUE if everything was OK, FALSE if not        }
  244.     VAR
  245.         Result         : WORD;
  246.     BEGIN
  247.  
  248.         Line := '';
  249.         Getline := FALSE;
  250.  
  251.         IF InitMode <> UNMASHMODE THEN BEGIN
  252.             LastError := INVINIT;
  253.             EXIT;
  254.         END;
  255.  
  256.         BLOCKREAD(BFile, Line[0], 1, Result);
  257.         IF Result <> 1 THEN BEGIN
  258.             LastError := CORRUPT;
  259.             EXIT;
  260.         END;
  261.  
  262.         BLOCKREAD(BFile, Line[1], ORD(Line[0]), Result);
  263.         IF Result = ORD(Line[0]) THEN BEGIN
  264.             Line := Mangle(Line);
  265.             Getline := TRUE;
  266.         END
  267.     END;
  268.  
  269.    
  270. (****************************************************************************)
  271.  
  272.     FUNCTION WTOA(N : WORD; W : INTEGER) : STRING;
  273.     VAR
  274.         Strg           : STRING;
  275.     BEGIN
  276.         STR(N:W, Strg);
  277.         WTOA := Strg;
  278.     END;
  279.  
  280.    
  281. (******************************************************************************)
  282.  
  283.     FUNCTION Mangler.MashError(VAR S : STRING) : BOOLEAN;
  284.         {- return the last error string }
  285.     BEGIN
  286.         {most of these messages are unlikely to occur.  You may remove most }
  287.         {of them to save memory }
  288.  
  289.         MashError := TRUE;
  290.         CASE LastError OF
  291.             000 : BEGIN {no error}
  292.                       S := '';
  293.                       MashError := FALSE; 
  294.                   END;
  295.             002 : S := 'File not found';
  296.             003 : S := 'Path not found';
  297.             004 : S := 'Too many open files';
  298.             005 : S := 'File access denied';
  299.             006 : S := 'Invalid file handle';
  300.             012 : S := 'Invalid file access code';
  301.             015 : S := 'Invalid drive number';
  302.             016 : S := 'Cannot remove current directory';
  303.             017 : S := 'Cannot rename across drives';
  304.             100 : S := 'Disk read error';
  305.             101 : S := 'Disk write error';
  306.             102 : S := 'File not assigned';
  307.             103 : S := 'File not open';
  308.             104 : S := 'File not open for input';
  309.             105 : S := 'File not open for output';
  310.             150 : S := 'Disk is write-protected';
  311.             151 : S := 'Unknown unit';
  312.             152 : S := 'Drive not ready';
  313.             154 : S := 'CRC error in data';
  314.             156 : S := 'Disk seek error';
  315.             157 : S := 'Unknown media type';
  316.             158 : S := 'Sector not found';
  317.             160 : S := 'Device write fault';
  318.             161 : S := 'Device read fault';
  319.             162 : S := 'Hardware failure';
  320.             203 : S := 'Insufficient memory';
  321.             INVINAM :S := 'Invalid filename';
  322.             INVINIT :S := 'Invalid Mash unit init';
  323.             CORRUPT : S := 'Invalid or corrupt MSH file';
  324.             ELSE
  325.                 S := 'Turbo runtime error ' + WTOA(LastError, 4);
  326.         END;
  327.     END;
  328.  
  329.    
  330. (****************************************************************************)
  331.  
  332.     PROCEDURE Mangler.SetSequence(Seq : STRING);
  333.         {- Set the encryption sequence (key) to be something other than the
  334. default   }
  335.         {  Gozintas: A string (the longer the better) containing any characters
  336. in    }
  337.         {  the range of (0-255)  Try to avoid using strings that will be
  338. duplicated   }
  339.         {  in the text to be encrypted.  A match between the key and the text
  340. results }
  341.         {  in strings of $FF characters in the MSH file that make the key
  342. easier to   }
  343.         {  crack by determined hackers                                         
  344.       }
  345.  
  346.     BEGIN
  347.         Id := Seq;
  348.     END;
  349.  
  350.    
  351. (****************************************************************************)
  352.  
  353.     FUNCTION Mangler.MashFile : BOOLEAN;
  354.         {- File conversion method.  Encrypts text file specified in Init method
  355. call }
  356.         {  and places encrypted binary junk into the .MSH file                 
  357.      }
  358.         {  Returns TRUE if success, FALSE if not                               
  359.      }
  360.     VAR
  361.         Strg           : STRING;
  362.         Result         : WORD;
  363.     BEGIN
  364.         WHILE (NOT EOF(TFile)) DO BEGIN
  365.             READLN(TFile, Strg);
  366.             WRITELN(Strg);
  367.             Strg := Mangle(Strg);
  368.             BLOCKWRITE(BFile, Strg, ORD(Strg[0]) + 1, Result);
  369.             IF Result <> LENGTH(Strg) + 1 THEN BEGIN
  370.                 WRITELN('Problem writing ' + FileName + '.MSH');
  371.                 HALT(1);
  372.             END;
  373.         END;                      {while}
  374.  
  375.     END;
  376.  
  377.    
  378. (****************************************************************************)
  379.  
  380.     PROCEDURE Mangler.Done;
  381.         {- Close up shop and boogie method}
  382.     BEGIN
  383.         CLOSE(BFile);
  384.         IF InitMode = MASHMODE THEN
  385.             CLOSE(TFile);
  386.  
  387.         InitMode := SOURMASH;
  388.     END;
  389.  
  390.    
  391. (****************************************************************************)
  392.     {unit initialization}
  393. END.                              {of unit mash}
  394. (****************************************************************************)
  395. (****************************************************************************)
  396.